import { executeCode } from './executionService';
import { analyzeCode } from './codeAnalysisService';
import { logger } from '../utils/logger';

// 测试用例接口
interface TestCase {
  input: string;
  expectedOutput: string;
  description?: string;
}

// 评测结果接口
interface EvaluationResult {
  passedTests: number;
  totalTests: number;
  testResults: TestResult[];
  codeQuality: {
    issues: any[];
    complexity: number;
    qualityScore: number;
    suggestions: string[];
  };
  overallScore: number; // 总分，满分100
  feedback: string;
}

// 测试结果接口
interface TestResult {
  passed: boolean;
  input: string;
  expectedOutput: string;
  actualOutput: string;
  description?: string;
  executionTime?: number;
}

/**
 * 评测代码
 * @param language 编程语言
 * @param code 代码内容
 * @param testCases 测试用例
 * @returns 评测结果
 */
export async function evaluateCode(
  language: string,
  code: string,
  testCases: TestCase[]
): Promise<EvaluationResult> {
  try {
    logger.info(`Evaluating ${language} code with ${testCases.length} test cases`);
    
    // 1. 代码质量分析
    const qualityAnalysis = await analyzeCode(language, code);
    
    // 2. 运行测试用例
    const testResults: TestResult[] = [];
    for (const testCase of testCases) {
      try {
        const executionResult = await executeCode(language, code, testCase.input);
        
        // 比较输出结果（忽略前后空格和换行符）
        const normalizedActual = executionResult.output.trim();
        const normalizedExpected = testCase.expectedOutput.trim();
        const passed = normalizedActual === normalizedExpected;
        
        testResults.push({
          passed,
          input: testCase.input,
          expectedOutput: normalizedExpected,
          actualOutput: normalizedActual,
          description: testCase.description,
          executionTime: executionResult.executionTime
        });
      } catch (error) {
        // 测试执行失败
        testResults.push({
          passed: false,
          input: testCase.input,
          expectedOutput: testCase.expectedOutput,
          actualOutput: error instanceof Error ? error.message : 'Unknown error',
          description: testCase.description
        });
      }
    }
    
    // 3. 计算测试通过率
    const passedTests = testResults.filter(r => r.passed).length;
    const totalTests = testResults.length;
    const testScore = Math.round((passedTests / totalTests) * 70); // 测试占70分
    
    // 4. 计算代码质量得分
    // 将complexity从0-100的范围（越低越好）转换为0-30的范围（越高越好）
    const qualityScore = Math.round(Math.max(0, 30 - (qualityAnalysis.complexity * 30 / 100)));
    
    // 5. 计算总分
    const overallScore = testScore + qualityScore;
    
    // 6. 生成评价反馈
    const feedback = generateFeedback(passedTests, totalTests, qualityAnalysis, testResults);
    
    return {
      passedTests,
      totalTests,
      testResults,
      codeQuality: {
        issues: qualityAnalysis.issues,
        complexity: qualityAnalysis.complexity,
        qualityScore,
        suggestions: qualityAnalysis.suggestions
      },
      overallScore,
      feedback
    };
  } catch (error) {
    logger.error(`Code evaluation error: ${error instanceof Error ? error.message : 'Unknown error'}`);
    throw error;
  }
}

/**
 * 生成评价反馈
 */
function generateFeedback(
  passedTests: number,
  totalTests: number,
  qualityAnalysis: any,
  testResults: TestResult[]
): string {
  const testPassRate = passedTests / totalTests;
  let feedback = '';
  
  // 根据测试通过率给出反馈
  if (testPassRate === 1) {
    feedback += '恭喜！你的代码通过了所有测试用例。';
  } else if (testPassRate >= 0.7) {
    feedback += `你的代码通过了${passedTests}/${totalTests}个测试用例，还需要一些改进。`;
  } else if (testPassRate >= 0.3) {
    feedback += `你的代码通过了${passedTests}/${totalTests}个测试用例，但还有较多问题需要解决。`;
  } else {
    feedback += `你的代码只通过了${passedTests}/${totalTests}个测试用例，需要大幅改进。`;
  }
  
  // 添加失败测试用例的错误提示
  const failedTests = testResults.filter(r => !r.passed);
  if (failedTests.length > 0) {
    feedback += '\n\n失败的测试用例：\n';
    failedTests.slice(0, 3).forEach((test, index) => {
      feedback += `${index + 1}. ${test.description || `测试 ${index + 1}`}: 预期输出 "${test.expectedOutput}"，实际输出 "${test.actualOutput}"\n`;
    });
    
    if (failedTests.length > 3) {
      feedback += `... 以及其他 ${failedTests.length - 3} 个测试用例\n`;
    }
  }
  
  // 添加代码质量建议
  if (qualityAnalysis.suggestions.length > 0) {
    feedback += '\n\n代码质量建议：\n';
    qualityAnalysis.suggestions.forEach((suggestion: string, index: number) => {
      feedback += `${index + 1}. ${suggestion}\n`;
    });
  }
  
  return feedback;
} 